use sha2::{Sha256, Sha512, Digest};
use chrono::{NaiveDateTime, Utc};

fn to_hex(data: &[u8]) -> String {
    data.iter().map(|b| format!("{:02x}", b)).collect()
}

pub fn create_hash(data: &str) -> Result<String, getrandom::Error> {
    let mut rand = [0u8; 32];
    getrandom::getrandom(&mut rand)?;
    let salt = to_hex(&rand);

    let mut hasher = Sha256::new();
    hasher.update(&salt);
    hasher.update(data);
    hasher.update(&salt);
    let hash = to_hex(&hasher.finalize());

    Ok(salt + &hash)
}

pub fn check_hash(data: &str, hash: &str) -> bool {
    if hash.len() != 128 {
        return false;
    }

    let salt = &hash[..64];

    let mut hasher = Sha256::new();
    hasher.update(salt);
    hasher.update(data);
    hasher.update(salt);
    let input_hash = to_hex(&hasher.finalize());

    hash[64..] == input_hash
}

pub fn sha512(str: &str) -> [u8; 64] {
    let mut hasher = Sha512::new();
    hasher.update(str);
    hasher.finalize().into()
}

pub fn now() -> NaiveDateTime {
    Utc::now().naive_utc()
}
